package nio;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.time.LocalDateTime;
import java.util.Iterator;

/**
 * \* Created with IntelliJ IDEA.
 * \* User: 康大
 * \* Date: 2019/4/29
 * \* Time: 15:31
 * \* To change this template use File | Settings | File Templates.
 * \* Description:
 * \    非阻塞式
 */
public class NonBlockingNIOTest {
    //客户端
    @Test
    public void client() {
        try(SocketChannel so = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8989))) {
            so.configureBlocking(false); //切换为非阻塞模式
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            byteBuffer.put(LocalDateTime.now().toString().getBytes());
            byteBuffer.flip();
            so.write(byteBuffer);
            byteBuffer.clear();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 服务端
    @Test
    public void server() throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false); // 切换为非阻塞模式
        // 绑定连接
        serverSocketChannel.bind(new InetSocketAddress(8989));
        // 获取选择器
        Selector selector = Selector.open();
        // 将通道注册到选择器上,并且指定监听事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        // 轮询式地获取选择器上已经“准备就绪”地事件
        while (selector.select() > 0) {
            // 获取当前选择器中所有注册的“选择器（已就绪的监听事）件”
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey sk = iterator.next();
                if (sk.isAcceptable()) {
                    // 接收就绪,获取客户端连接
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    // 将该通道注册到选择器上
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (sk.isReadable()) {
                    // 读就绪，获取“读就绪”的通道
                    SocketChannel socketChannel = (SocketChannel) sk.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                    int len = 0;
                    while ((len = socketChannel.read(byteBuffer)) != -1) {
                        byteBuffer.flip();
                        System.out.println(new String(byteBuffer.array(), 0, len));
                        byteBuffer.clear();
                    }
                }
                // 取消选择键 SelectionKey
                iterator.remove();
            }
        }

    }
}
